(function(window,angular,$){
	'use strict';
	/**
	 * zhx.camera.monitor plugin
	 *
	 * Author : Vicco Wang
	 * Date : 2017/03/29
	 * 
	 * [Monitor description]
	 *
	 */
	var Monitor = angular.module('zhx.camera.monitor',[]);

	/**
	 * Monitor Provider
	 */
	Monitor.provider('zhx.camera.monitor',function(){

		/**
		 * default options of plugin
		 * @type {Object}
		 */
		var config = {
			videoStreamUrl 		: 'js/data/test_hk.json',
			videoPrarms : {
				addVideoKey 	: 'add',
				removeVideoKey 	: 'remove',
				heartBeatKey 	: 'heartBeat',
				qualityKey		: 'HD'
			},
			hearBeatInterval 	: 15    //heart beat second
		};

		//extend options of default and custom
		this.config = function(cfg){
			config = angular.merge({}, config, cfg);
		};

		//public methods for provider
		this.$get = function(){
			return {
				getConfig		: function(){
					return config;
				}
			}
		};

	});

	/**
	 * zhx.camera.monitor main service
	 */
	Monitor.factory('zhx.camera.service', ['$timeout','$http','$q','$interval','zhx.camera.monitor',function($timeout,$http,$q,$interval,cameraMonitor){

		var service = {};

		//宫格数量展示方式数组,这里最大能添加至10个CAMERA, 添加更多CAMERA时,目前需要用户手动移除其他后再次添加
		var cameraLenArray = [1,2,3,4,6,9,10];

		/**
		 * 这里存放1-10个数据重构后的CAMERA OBJECT
		 * 数组顺序对应CAMERA 1 - 10; 如果CAMERA被移除,值会被置为NULL,表示CAMERA在页面上已清空,下次再次新增CAMERA时会优先填充最靠前的MONITOR宫格;
		 * @type {Array} Object
		 */
		var cameraMonitorArray = [];

        /**
         * 创建一个新建标识位,在用户连续点击创建Camera时,需要保证数据结构创建完毕后才可以继续创建;
         * @type {boolean}
         */
		var cameraIsCreating = false;

		//根据自生成的CAMERA ID判断CAMERA是否在已插入页面的CAMERA数组中;
		var __isCameraInArray = function(camera){
			for( var i = 0; i < cameraMonitorArray.length; i++){
				var arrayCamera = cameraMonitorArray[i];
				if( arrayCamera ){
					if( arrayCamera.id === camera.id ) return true;
				}
			}
			return false;
		};

		/**
		 * 判断数组中是否含有NULL
		 * @return {[type]} [NULL值的下标 / 数组不含NULL]
		 */
		var __isNullInArray = function(){
			for( var i = 0; i < cameraMonitorArray.length; i++){
				if(  cameraMonitorArray[i] === null ) return i;
			}
			return -1;
		};

        /**
         * 判断一个真实的传入的数据对象中的Camera是否在已经打开的Camera列表中,该方法可以保证打开的Camera的唯一性
         * @param realCameraId
         * @returns {boolean}
         */
		service.isCameraInArray = function(realCameraId){
            for( var i = 0; i < cameraMonitorArray.length; i++){
                var arrayCamera = cameraMonitorArray[i];
                if( arrayCamera ){
                    if( arrayCamera.cameraProp.cameraId === realCameraId ) return true;
                }
            }
            return false;
        };

		service.getCameraArray = function(){
		    return cameraMonitorArray;
        };

		service.emptyCameraArray = function(){
            cameraMonitorArray = [];
        };

		service.getCreatingState = function(){
		    return cameraIsCreating;
        };

		//通过URL从后端获取到当前Camera的RTMP直播URL;
        //TODO 这里模拟了参数 { busId : xxx, cameraId : xxx }
		service.createVideoStream = function(scope, params){
            //添加监控对象不能超过最大值,如果有空余宫格位置则可以继续添加
            if( cameraMonitorArray.length >= cameraLenArray[ cameraLenArray.length - 1 ] && __isNullInArray() === -1 ){
                alert('监控位已满,请先移除再添加.');
                return;
            }

		    //如果正在创建,则不能连续创建;
		    if( cameraIsCreating ) return;

            //设置一个创建标识状态
            cameraIsCreating =  true;

			var cameraConfig = cameraMonitor.getConfig();

            //TODO 这是假数据
			var postParams = {
                busId 		: params.busId,
                cameraId 	: params.cameraId,
                method 		: cameraConfig.videoPrarms.addVideoKey
            };
			$http({
				url : cameraConfig.videoStreamUrl,
				params : postParams
			}).then(function(res){
				var data =  res.data.data;
				if( data ){
					//获取成功后通过内部服务封装成一个Camera对象,在后续操作中都会操作该对象;
					service.createNewCameraObjectByStream(data,postParams).then(function(res){
                        //该Promise会直到Camera Object完全插入至DOM后,才会resolve;
					    var createSWFpromise = $q.defer();
						//获取到的对象最终生成一个JWPlayer插入到对应的MonitorDOM中;
						service.addCameraSWFToSection(scope,res,createSWFpromise);
                        //重置创建标识位
                        createSWFpromise.promise.then(function(){
                            cameraIsCreating = false;
                        })
					})
				}
			},function(error){
				console.warn(error);
			})

		};

		/**
         *
         * yCg4iMBYCmQNiQ
		 * [createNewCameraObjectByStream description]
		 * @param  {[type]} cameraProp [自组装Camera对象属性]
         *                  extendProp [接收结果前,指定的参数,比如车辆ID和CameraID等,需要和CameraProp合并]
		 * @return {[type]}            [description]
		 */
		service.createNewCameraObjectByStream = function(cameraProp,extendProp){

			if( !cameraProp || !extendProp ) return;

			var createDefer = $q.defer();
			//生成不重复的随机ID
			var __createId = function(){
				var date,seed,char,randomChar="",string;
		        date = new Date().getTime();
		        seed = parseInt( Math.random(1,1000) * 1000 );
		        char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
		        for( var i = 0 ; i < 5; i++ ){
		            randomChar += char.charAt(Math.floor(Math.random() * 52));
		        }
		        string = String(seed + date) + randomChar;
		        return 'monitor-' + string.substr(5);
			};

			//创建ZhxPlayer的Camera Object;
			var __createMonitor = function(){
				/**
				 * 自定义CameraObject
				 * @type {Object}
				 */
				var cameraObject = {
					id : __createId(),							//随机ID
					cameraProp : angular.merge({}, cameraProp, extendProp ) || undefined,		//从URL中获取到的参数, 包括 rmtpURL 和 type 等其他数据
					player : null,								// jwPlayer Object
					position : null,							//CAMERA显示位置对应1-10
					heartBeatInterval : null 					//HeartBeat $Interval对象
				},
				//ZhxPlayer参数配置
                cameraOpts = {
				    id   : cameraObject.id,
                    file : cameraObject.cameraProp.url,
                    name : cameraObject.cameraProp.name,
                    autoStart: true,        //unused
                    controls: false,        //unused
                    mute : true,            //unused
                    screenRatio : "4:3",    //initial
                    width : '100%',
                    height : '100%',
                    player : 'lib/zhx.swfplayer/swf/zhx.player.swf'
                };

                //zhxplayer wrapper dom
				var dom = angular.element('<div id='+ cameraObject.id +' />');
				    dom.hide();
                //setup初始化ZhxPlayer并赋值给自定义的cameraObject
                cameraObject.player = ZhxPlayer(dom[0]).setup(cameraOpts);

				/**
				 * cameraObject Events 
				 * 每次生成新的Camera时,都会为期绑定以下监听事件
				 */
				//TODO 正常播放后需要发送心跳状态
				cameraObject.player.on('play',function(res){
					//首先查看是否有延迟对象并将其清空;
					if( cameraObject.heartBeatInterval ) window.clearInterval( cameraObject.heartBeatInterval );

					var cameraConfig = cameraMonitor.getConfig();

					//配置心跳延迟
					cameraObject.heartBeatInterval = window.setInterval(function(){
						//TODO 假数据 http发送心跳
						$http({
							url : cameraConfig.videoStreamUrl,
							params : {
								method 	: cameraConfig.videoPrarms.heartBeatKey
							}
						}).then(function(res){
							//接收服务器心跳成功回调

						})
					},cameraMonitor.getConfig().hearBeatInterval * 1000 || 30000 );
				});

				//TODO 移除后需要发送停止心跳状态
				cameraObject.player.on('remove',function(res){
					//取消发送心跳
					if( cameraObject.heartBeatInterval ) window.clearInterval( cameraObject.heartBeatInterval );

				});

				/*
				 * 添加进Monitor Array 数组中
				 */
				if( !__isCameraInArray(cameraObject) ){
					/**
					 * 这里需要判断数组中是否含有NULL值,如果含有NULL值,则新建的CAMERA对象则覆盖数组中最近的一个NULL
					 */
					var nullPosition = __isNullInArray();
                    //这里返回值为-1表示没有在数组中找到值为NULL的对象,否则的话返回数组下标
					if( nullPosition !== -1 ){
                        //将CAMERA对象插入数组NULL位置
						cameraMonitorArray.splice(nullPosition,1,cameraObject);
						cameraObject.position = nullPosition + 1;
					} else {
                        //直接插入数组末尾
						cameraMonitorArray.push(cameraObject);
						cameraObject.position = cameraMonitorArray.length;
					}
				}

				createDefer.resolve( cameraObject );
				
			};

			__createMonitor();

			return createDefer.promise;

		};

		/**
		 * 该方法会将封装好的Camera对象根据条件插入到DOM树中,这里会判断插入到哪个CameraDOM容器中;
		 * @param {object} scope     [创建Camera的Scope]
         * @param {object} cameraObject     [Camera Object]
         * @param {object} createSWFpromise  [Camera create promise]
		 */
		service.addCameraSWFToSection = function( scope, cameraObject,createSWFpromise ){

			var cameraDom = cameraObject.player.getContainer(),
				cameraPos = cameraObject.position;
				/**
				 * 当CameraObject最终准备完成时,先检测是否需要变更当前宫格布局(是不是足够显示新增的Camera);然后才会将Camera添加至DOM;
				 * @type {[type]}
				 */
				scope.$broadcast('zhx.camera.monitor.resize',{
				    cameraObject: cameraObject,
                    cameraDom: cameraDom,
                    cameraPos : cameraPos,
                    createPromise : createSWFpromise
				});

		};

		/**
		 * 移除一个Camera,此处移除将移除DOM,数组,以及调用中断视频流
		 * @param  {[type]} cameraObject [description]
		 * @return {[type]}              [description]
		 */
		service.removeCameraSWF = function(cameraObject,monitorDom){
			var removeDefer = $q.defer();
			//remove target camera in array
			for( var i = 0; i < cameraMonitorArray.length; i++){
				//数组中可能存在为NULL的值,表示宫格空位
				if( cameraMonitorArray[i] !== null ){
					if( cameraMonitorArray[i].id === cameraObject.id ){
						//这里移除数组中的CAMERA后,将值置为NULL,表示页面该宫格空位,待下次新增CAMERA时,会优先填充该数组位置
						cameraMonitorArray.splice(i,1,null);
						break;
					}
				}
				
			}

			//每次移除CAMERA后,倒序遍历数组,将所有排在末尾的NULL值全部移除,仅保留数组中值和值中间的的NULL对象,表示当前宫格内的MONITOR空白
			for( var j = cameraMonitorArray.length - 1; j >= 0 ; j--){
				if( cameraMonitorArray[j] !== null ){
					break;
				} else {
					cameraMonitorArray.splice(j,1);
				}
			}

			//remove jwPlayer
			cameraObject.player.remove();
			//removeDom
			monitorDom.empty();

			removeDefer.resolve();

			return removeDefer.promise;

		};

		/**
		 * 该方法主要用于根据当前已添加进CAMERA数组的长度判断当前页面展示几宫格;
		 * @param  {[type]} len   [当前添加的是第几个CAMERA]
		 * @return {[type]}       [description]
		 */
		service.reSizeCameraSize = function(len,state){
			//这里判断只有切换时宫格数不够展示CAMERA时才会切换宫格展示方式;
			if( state ){
				switch( len ){
					case 1 :
						return cameraLenArray[0];
					case 2 :
						return cameraLenArray[1];
					case 3 : 
						return cameraLenArray[2];
					case 4 : 
						return cameraLenArray[3];
					case 5 || 6:
						return cameraLenArray[4];
					case 7 || 8 || 9:
						return cameraLenArray[5];
					case 10:
						return cameraLenArray[6];
				}
			}
			return len;
		};

		return service;

	}]);

	/**
	 * zhx.camera.monitor main controller
	 */
	Monitor.controller('zhx.camera.monitor.mainCtrl',["$scope","$element","$q","$timeout","zhx.camera.service",function($scope,$element,$q,$timeout,monitorService){

		//默认展示宫格方式
		// 1, 2, 3, 4, 6, 9, 10
		$scope.sectionOptions = {
			monitorSize : $scope.options.monitorDisplaySize || 6,		//init monitor count
			focusMonitor : null		//focus monitor
		};

		this.getMonitorSize = function(){
			return $scope.sectionOptions.monitorSize;
		};

		this.setMonitorSize = function(size){
            $scope.sectionOptions.monitorSize = size;
        };

		this.getFocusMonitor = function(){
			return $scope.sectionOptions.focusMonitor;
		};

		this.setFocusMonitor = function(monitor){
            //判断当前需要FOCUS的MONITOR是不是同一个,如果是同一个则实现取消选择功能
			if( $scope.sectionOptions.focusMonitor && $scope.sectionOptions.focusMonitor.id === monitor.id ){
				$scope.sectionOptions.focusMonitor = {};
				//静音
				$timeout(function(){
					monitor.player.setMute(true);
				},100);

			} else {
				$scope.sectionOptions.focusMonitor = monitor;
				//取消静音
				$timeout(function(){
					monitor.player.setMute(false);
				},100)
			}

		};

        /**
         * 在父控制器接收是否最大化某个Camera;
         * res {Object}   Camera Object
         */
        this.setCameraMax = function(camera){
            /**
             * 每个Monitor在关闭后,会返回一个是否完成关闭的Promise对象;
             * 这里用于检查是否全部的Monitor都完成了关闭;
             * @type {Array}
             */
            var promiseArray = [];
            //广播移除所有Camera事件
            $scope.$broadcast('zhx.camera.monitor.removeCamera',{ state : 'removeAll', promises : promiseArray });
            //等待全部移除后执行新增操作
            $q.all(promiseArray).then(function(){
                //设置宫格为1,表示最大化
                $scope.sectionOptions.monitorSize = 1;
                //新增目标Camera;
                monitorService.createVideoStream($scope,  camera.cameraProp.busId, camera.cameraProp.cameraId);
            });

        };

		/**
		 * 在服务创建完一个CAMERA对象后,首先应该在这里判断是否需要变更页面的宫格展示方式;这里处理的逻辑为:
		 * 在新增CAMERA后,如果宫格不够,则变更为更高一级的宫格展示,如果宫格足够,则保持目前展示方式不变,直到需要展示的CAMERA超过了当前展示的宫格数量;
		 * 最大不超过10个CAMERA;
		 * @param  {[type]} ev           [description]
		 * @param  {[type]} res){			var subRes        [description]
		 * @param  {[type]} 50);		}     [description]
		 * @return {[type]}              [description]
		 */
		$scope.$on('zhx.camera.monitor.resize',function(ev,res){
			//判断 当前展示的宫格数是否在添加新CAMERA后足够使用;
			var subRes =  $scope.sectionOptions.monitorSize < res.cameraPos,
				substractLen = subRes ? res.cameraPos : $scope.sectionOptions.monitorSize,
				//计算最新的宫格展示方式 2,3,4,9,10 etc;
				newSize = monitorService.reSizeCameraSize(substractLen, subRes);
			//在完成判断宫格后,会变更当前宫格展示方式
			$scope.sectionOptions.monitorSize = newSize;
			//页面展示方式变更完毕后就将当前最新创建的CAMERA插入页面;
			$timeout(function(){
				$scope.$broadcast('zhx.camera.monitor.add',res);
			},50);
		});

        /**
         * 更新自定义Tree节点数据
         * @param treeData
         * @returns {Promise}
         */
        $scope.reBuildTreeData = function(treeData){
            var rebuildDeffered = $q.defer();
            if( treeData && treeData.length){
                for( var i = 0 ; i < treeData.length; i++ ){
                    var node = treeData[i];
                    //为每个节点保存一个初始的名称,保证后面修改了名称后还能通过该属性将初始名称该回
                    node.sourceName = node.name;
                    //line node
                    if( !angular.isUndefined(node.lineId) && angular.isUndefined(node.busId) && angular.isUndefined(node.cameraId) ){
                        node.iconSkin = "treeLineNode";
                    //bus number node
                    } else if( !angular.isUndefined(node.busId) && angular.isUndefined(node.cameraId) ){
                        node.iconSkin = "treeBusNode";
                    //child camera node
                    } else if( !angular.isUndefined(node.cameraId) ){
                        node.iconSkin = "treeCameraNode";
                    }

                }

                rebuildDeffered.resolve(treeData);
            }

            return rebuildDeffered.promise;

        };

        /**
         * 构建左侧树
         * @param treeData
         */
        var ztree;

        $scope.createVideoTree = function(treeData){

            var zSettings = {
                view : {
                    showLine : false,
                    nameIsHTML : true
                },
                data : {
                    simpleData :{
                        enable : true
                    }
                },
                callback: {
                    onClick : ztreeOnClick
                }
            };

            function ztreeOnClick(event,treeId,treeNode){

                if( !treeNode.cameraId) return false;

                if( monitorService.isCameraInArray(treeNode.cameraId) ){
                    $scope.$broadcast('zhx.monitor.external.focus',treeNode.cameraId);
                    return false;
                }

                /**
                 * 根据参数创建监视器
                 * @type {{busId: *, cameraId: *}}
                 */
                var params = {
                    busId : treeNode.busId,
                    cameraId : treeNode.cameraId
                };
                monitorService.createVideoStream($scope, params);

            }

            var treeDom = $element.find("#camera-monitor-tree > ul.ztree");

            $scope.reBuildTreeData(treeData).then(function(res){
                //initial ztree
                ztree = $.fn.zTree.init( treeDom, zSettings, res );
            });

        };

        /**
         * 根据用户传入的zTree节点的数据来生成一棵树
         */
		$scope.$watch('options.treeData',function(treeData){
		    if( treeData && treeData.length ){
                $scope.createVideoTree(treeData);
            }
        });

        /**
         * 监控已经添加的Monitor对象变化
         */
		$scope.$watchCollection(function(){
		    return monitorService.getCameraArray()
        },function(newVal, oldVal){
            if( newVal && newVal !== oldVal ){
                if( !ztree ) return;
                var treeNodes = ztree.transformToArray( ztree.getNodes() );
                //update tree nodes style by global cameraArray
                for(var i = 0; i < treeNodes.length; i++){
                    var node = treeNodes[i];
                    if( monitorService.isCameraInArray(node.cameraId) ){
                        node.name = node.sourceName + '<span class="activeCamera"></span>';
                    } else {
                        node.name = node.sourceName;
                    }
                    ztree.updateNode(node);
                }
            }
        })

	}]);

	/**
	 * zhx.camera.monitor main directvie
	 */
	Monitor.directive('zhxCameraMonitor',["$timeout","zhx.camera.service",function($timeout,monitorService){
		return {
			restrict : 'E',
			scope : {
				options : '='
			},
			replace: true,
			controller : 'zhx.camera.monitor.mainCtrl',
			link : function( scope, tElement, tAttrs ){

				//set monitor count
				scope.setMonitorSize = function(number){
					scope.sectionOptions.monitorSize = number;
				};

				//设置一个DataTime
				// window.setInterval(function(){
				// 	scope.dateTimeCount = moment().format('YYYY/MM/DD HH:mm:ss');
				// },1000);

			},
			templateUrl : 'zhx.camera.monitor.tpl.vicco'
		}
	}]);

	Monitor.directive('monitorSection',["$timeout","zhx.camera.service",function($timeout,cameraService){
		return {
			restrict : 'E',
			scope : {
				options : '='
			},
			replace : true,
			require : '^?zhxCameraMonitor',
			link : function( scope, tElement, tAttrs, monitorController ){

                //diffrent monitor size, use diffrent prop layer;
				scope.useColumnLayer = false;	// 3
				scope.useFlexLayer = false;		// 4
				scope.useFloatLayer = false;	// 6
				scope.useSmallFlexLayer = false; //9
				scope.useAllFlexLayer = false;		//10

				//watch monitor count
				scope.$watchCollection('options',function(newOptions){
					if( newOptions && newOptions.monitorSize ){
						scope.monitorSize = newOptions.monitorSize;
						scope.useColumnLayer = scope.monitorSize === 3;
						scope.useFlexLayer = scope.monitorSize === 2 || scope.monitorSize === 4;
						scope.useFloatLayer = scope.monitorSize === 6;
						scope.useSmallFlexLayer = scope.monitorSize === 9;
						scope.useAllFlexLayer = scope.monitorSize === 10;
					}
				});

				//fixes 360browser 
				if( tElement[0].getBoundingClientRect().height === 0 ){
					var _setCameraOuterHeight = function(){
						$timeout(function(){
							var windowHeight = document.documentElement.clientHeight;
							if( windowHeight ) tElement.outerHeight(windowHeight - 80);
						},50);
					};
					$(window).on('resize',_setCameraOuterHeight);
					_setCameraOuterHeight();
				}

			},
			templateUrl : 'zhx.camera.monitor.list.vicco'
		}
	}]);

	Monitor.directive('monitorCamera',["$timeout","$q","zhx.camera.service",function($timeout,$q,monitorService){
		return {
			restrict : 'E',
			scope : {
				cameraPos : '='
			},
			replace : true,
			require : '^?zhxCameraMonitor',
			link : function( scope, tElement, tAttrs, monitorCtrl ){

				//当前Monitor Fcous状态
				scope.focusState = false;
				//鼠标移动状态, mouseover or mouseleave
				scope.mouseOverState = false;
				//is show loading or not
				scope.monitorLoading = false;

				//Camera Wrapper Dom
				var cameraMonitorDomWrapper = tElement.find('.monitor-camera-main');

				//Monitor获得高亮边框焦点
				scope.focusMonitor = function(event){
					var ev = event || window.event;
					ev.stopPropagation();
					//如果当前MONITOR没有CAMERA对象,则不触发FOCUS操作
					if( scope.cameraObject ){
						//播放后才可以FOCUS
						scope.cameraObject.player.getState() === 'playing' && monitorCtrl.setFocusMonitor( scope.cameraObject );

                    }

				};

				//关闭Monitor
				scope.closeMonitor = function(event){
					var ev = event || window.event;
					ev.stopPropagation();
					if( scope.cameraObject ){
						monitorService.removeCameraSWF( scope.cameraObject, cameraMonitorDomWrapper )
						.then(function(){
							scope.focusState = false;
							scope.cameraObject = undefined;
							scope.monitorLoading = false;
						});
					}

				};

                //鼠标悬浮montiors事件,展示出 关闭/最大化 etc.按钮
				scope.displayCtrlBtn = function(event){
				    var ev = event || window.event,
				        target = angular.element(ev.target);
				    if( !scope.cameraObject ) return;
				    if( target.hasClass('monitor-event-mask') || target.hasClass('camera-monitor-icon') ){
                        scope.mouseOverState = true;
                    }
                };

                //鼠标离开montiors事件,隐藏 关闭/最大化 etc.按钮
				scope.hideCtrlBtn = function(){
                    if( !scope.cameraObject ) return;
                    scope.mouseOverState = false;
                };

                /**
                 * Monitor最大化当前Camera
                 */
				scope.maxMonitor = function(){
                    /**
                     * 这里排除创建队列阻塞造成,创建状态仍未初始化,所以必须保证创建状态初始化后,才可以最大化窗口,
                     * 否则最大化窗过程中的创建会失败;
                     */
				    if( monitorService.getCreatingState() ){
				        alert('正在创建视频,请稍候再操作.');
				        return;
                    }
                    monitorCtrl.setCameraMax( scope.cameraObject );
                };

				/**
				 * 每一个监控窗口都是独立指令,在这里接收到创建广播后来插入新的CAMERA
                 * @param res [Object]  Camera Object
				 */
				scope.$on('zhx.camera.monitor.add',function(ev,res){
					//判断是否插入是当前CAMERA位置;
					if( scope.cameraPos === res.cameraPos ){
						scope.cameraObject = res.cameraObject;
						tElement.find(".monitor-camera-main").append( res.cameraDom );
						//插入DOM后,该创建过程完成,执行成功Promise;
						res.createPromise.resolve('created Camera Finish');
					}
				});

				/**
				 * 该方法会在	切换宫格展示方式时,如果从多宫格切换至少公共,且当前宫格中含有CAMERA对象,则会调用;
				 * 
				 * 为每一个CAMERA窗口创建一个销毁事件,ng-if会销毁当前作用域和DOM;
				 * @param  {[type]} ev             [description]
				 * @return {[type]}                [description]
				 */
				scope.$on('$destroy',function(ev,res){
					if( scope.cameraObject ){
						monitorService.removeCameraSWF( scope.cameraObject, cameraMonitorDomWrapper ).then(function(){
                            scope.focusState = false;           //取消聚焦
                            scope.cameraObject = undefined;     //移除当前作用域下的CameraObject
                        });
					}
				});

                /**
                 * 这里接收到的是外部传入的事件,是否移除当前Camera对象;
                 * 判断传入ID相同或者状态为 全部移除时, 均会移除该Camera;
                 */
				scope.$on('zhx.camera.monitor.removeCamera',function(ev,res){
                    if( scope.cameraObject ){
                        var removeDefer = $q.defer();   //创建一个临时的延迟对象
                        res.promises.push( removeDefer.promise );
                        if( ( res.id && res.id === scope.cameraObject.id ) || res.state === 'removeAll' ){
                            monitorService.removeCameraSWF( scope.cameraObject, cameraMonitorDomWrapper ).then(function(){
                                scope.focusState = false;       //取消聚焦
                                scope.cameraObject = undefined; //移除当前作用域下的CameraObject
                                removeDefer.resolve();
                            });
                        }
                    }
                });

				/**
				 * 每一个CAMERA需要监控当前是否FOCUS, 监控的值为FOCUS的CAMERA.POSITION
				 */
				scope.$watchCollection(function(){
					return monitorCtrl.getFocusMonitor();
				},function(monitor){
					if( monitor && scope.cameraObject ){
						//重置当前CAMERA属性
						scope.focusState = false;
						//当前CAMERA非点击状态需要静音
						scope.cameraObject.player.setMute(true);
						if( monitor.id && monitor.id === scope.cameraObject.id ){
							scope.focusState = true;
						}
					}

				});

                /**
                 * 接收上级通知自动聚焦当前Camera,目前用于左侧Tree上点击已创建的Camera后进行Focus操作
                 */
				scope.$on("zhx.monitor.external.focus",function(event,cameraId){
				    if( !scope.cameraObject ) return;
				    if( cameraId === scope.cameraObject.cameraProp.cameraId ){
                        if( scope.cameraObject ){
                            //播放后才可以FOCUS
                            $timeout(function(){
                                scope.cameraObject.player.getState() === 'playing' && monitorCtrl.setFocusMonitor( scope.cameraObject );
                            });
                        }
                    }
                });

				/**
				 * 每一个CAMREA在READY阶段需要做一些工作;比如:设置一个lOADING等待交互;
				 */
				var cameraReadyWatch = scope.$watchCollection('cameraObject',function(cameraObject){
					if( cameraObject ){
						//set loading
						scope.monitorLoading = true;
						//before play remove loading
						cameraObject.player.on('beforePlay',function(res){
							scope.monitorLoading = false;
						});
						//clear Watch
						cameraReadyWatch();
					}
				})

			},
			templateUrl : 'zhx.camera.monitor.player.vicco'
		}
	}]);

	/**
	 * caching default template
	 */
	Monitor.run(['$templateCache',function($templateCache){

		//main wrapper template
		$templateCache.put('zhx.camera.monitor.tpl.vicco',
			'<div class="zhx-camera-monitor">' +
				//tree left, with plugin or without plugin
				'<div class="camera-monitor-navigation">' +
					//tree
                    '<div id="camera-monitor-tree">' +
                        '<ul class="ztree"></ul>' +
                    '</div>' +
					// '<span style="display:inline-block;margin:10px;color:#fff;cursor:pointer;" ng-click="addMonitorStream();">ADD STREAM</span>' +
				'</div>' +
				//main right
				'<div class="camera-monitor-main">' +
					//line name / bus number / date time etc.
					// '<div class="camera-monitor-header">' +
					// 	'<div class="line-name">K211</div>' +
					// 	'<div class="bus-number">陕A7826C</div>' +
					// 	'<div class="select-camera"></div>' +
					// 	// '<div class="time" ng-bind="dateTimeCount"></div>' +
					// '</div>' +
					//main camera monitor screen / 1x 2x 6x 9x etc.
					'<div class="camera-monitor-section">' +
						'<monitor-section options="sectionOptions"></monitor-section>' +
					'</div>' +
					//change camera display area position;
					'<div class="camera-monitor-type">' +
						'<ul>' +
							'<li ng-click="setMonitorSize(1)" ng-class="{ active : sectionOptions.monitorSize == 1 }"></li>' +
							'<li ng-click="setMonitorSize(2)" ng-class="{ active : sectionOptions.monitorSize == 2 }"></li>' +
							'<li ng-click="setMonitorSize(3)" ng-class="{ active : sectionOptions.monitorSize == 3 }"></li>' +
							'<li ng-click="setMonitorSize(4)" ng-class="{ active : sectionOptions.monitorSize == 4 }"></li>' +
							'<li ng-click="setMonitorSize(6)" ng-class="{ active : sectionOptions.monitorSize == 6 }"></li>' +
							'<li ng-click="setMonitorSize(9)" ng-class="{ active : sectionOptions.monitorSize == 9 }"></li>' +
							'<li ng-click="setMonitorSize(10)" ng-class="{ active : sectionOptions.monitorSize == 10 }"></li>' +
						'</ul>' +
					'</div> ' +
				'</div>' +
			'</div>');

		//support 10 monitors display in one screen
		$templateCache.put('zhx.camera.monitor.list.vicco',
			'<div class="camera-list" ng-style="{ height : cameraWrapperHeight }" ng-class="{ float_layer_3 : useColumnLayer, flex_layer : useFlexLayer, flex_layer_vhs : useSmallFlexLayer, flex_layer_all : useAllFlexLayer, float_layer_6 : useFloatLayer }">' +
				'<monitor-camera camera-pos="1" ng-class="{ full: monitorSize == 1, flex_half : monitorSize == 2, flex_vh : monitorSize == 4, float_big : monitorSize == 6 }" ng-if=" monitorSize "></monitor-camera>' +
				'<monitor-camera camera-pos="2" ng-class="{ flex_half : monitorSize == 2, flex_vh : monitorSize == 4, float_small : monitorSize == 3 || monitorSize == 6 }" ng-if=" monitorSize >= 2 "></monitor-camera>' +
				'<monitor-camera camera-pos="3" ng-class="{ column_half_v : monitorSize == 3, flex_vh : monitorSize == 4, float_small : monitorSize == 3 || monitorSize == 6 }" ng-if=" monitorSize >= 3 "></monitor-camera>' +
				'<monitor-camera camera-pos="4" ng-class="{ flex_vh : monitorSize == 4 }" ng-if=" monitorSize >= 4 "></monitor-camera>' +
				'<monitor-camera camera-pos="5" ng-if=" monitorSize >= 6 "></monitor-camera>' +
				'<monitor-camera camera-pos="6" ng-if=" monitorSize >= 6 "></monitor-camera>' +
				'<monitor-camera camera-pos="7" ng-if=" monitorSize >= 9 "></monitor-camera>' +
				'<monitor-camera camera-pos="8" ng-if=" monitorSize >= 9 "></monitor-camera>' +
				'<monitor-camera camera-pos="9" ng-if=" monitorSize >= 9 "></monitor-camera>' +
				'<monitor-camera camera-pos="10" ng-if=" monitorSize >= 10 "></monitor-camera>' +
			'</div>');

		//CAMERA
		$templateCache.put('zhx.camera.monitor.player.vicco',
			'<div class="monitor-block" ng-mouseover="displayCtrlBtn($event);" ng-mouseleave="hideCtrlBtn($event);">' +
				'<div class="monitor-event-mask" ng-class="{ focuseBorder : focusState }" ng-click="focusMonitor($event)"></div>' +
				'<div class="monitor-loading-mask" ng-if="monitorLoading">加载中...</div>' +
				'<div class="camera-monitor-icon close-monitor monitor-font icon-close" ng-if="cameraObject && mouseOverState" ng-click="closeMonitor($event)"></div>' +
				'<div class="camera-monitor-icon max-size monitor-font icon-zuidahua" ng-if="cameraObject && mouseOverState && $parent.monitorSize !== 1 " ng-click="maxMonitor($event)"></div>' +
				'<div class="camera-monitor-icon monitor-speaker monitor-font icon-laba" ng-if="focusState"></div>' +
				'<div class="monitor-camera-main"></div>' +
			'</div>');

	}]);

})(window,angular,jQuery);